fn main() {
  let s = String::from("test slice");
  let s1 = &s[0..4]; //左开右闭
  let s1 = &s[0..=4]; //算上尾巴
  let s1 = &s[..=4]; //从头到4 即 test空格
  let s1 = &s[4..]; // slice
  let s1 = &s[..]; //test slice
  //s1.push_str //slice 就没有push方法
  println!("{}", s1); //test

  // 注意非英文字符
  // let ch = String::from("你好");
  // let ch1 = &ch[0..1];
  // println!("{}", ch1); //报错:
/*
thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside '你' (bytes 0..3) of `你好`', 04.3slices\src\main.rs:11:14
stack backtrace:
*/

  // 字面量字符串 就是 slice
  let mut ss = "ahhh"; //字符串字面量 其类型为 &str, 是不可变引用 (因此字符串字面量是不可变的)

  /** “字符串 slice” 的类型声明写作 &str (没错, 这样写, 是个固定写法, 但只代表 字符串slice, 而不代表其它类型的slice, 比如数组)*/
  fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() { // iter 方法返回集合中的每一个元素，而 enumerate 包装了 iter 的结果，将这些元素作为元组的一部分来返回。enumerate 返回的元组中，第一个元素是索引，第二个元素是集合中元素的引用。这比我们自己计算索引要方便一些。
      if item == b' ' {
        return &s[0..i];
      }
    }

    &s[..]
  }
  let my_string = String::from("hello world");
  // first_word 中传入 `String` 的 slice
  let word = first_word(&my_string[..]);

  let my_string_literal = "hello world";

  // first_word 中传入字符串字面值的 slice
  let word = first_word(&my_string_literal[..]);

  // 因为字符串字面值 **就是** 字符串 slice，
  // 这样写也可以，即不使用 slice 语法！
  let word = first_word(my_string_literal);


  /** 其他类型的 slice*/
  let a = [1, 2, 3, 4]; //[i32;4]
  let a1 = &a[1..3]; //↑数组[i32;4] 对应的slice类型为 &[i32]
  println!("{:?}", a1); //[2, 3]
}
